﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Fis.Win.Utils;

namespace Fis.Win.Forms
{
    public partial class AccountListForm : ListForm
    {
        public AccountListForm()
        {
            InitializeComponent();
            InitializeKindFilter();
            RightsName = "BD.ACCOUNT";
        }

        public override void InitializeBinding()
        {
            var d = ViewModel["viewData"] as DataTable;
            d.DefaultView.Sort = "FCODE";
            treeList1.DataSource = d;
            treeList1.ExpandAll();

            UIUtils.LookUpBinding(reType, CacheContext.GetCache("accSystem"), "caption", "key");
            UIUtils.LookUpBinding(reJD, CacheContext.DebitCreditCache(), "display", "value");
            UIUtils.LookUpBinding(reWB, CacheContext.WBHSCache(), "display", "value");
            UIUtils.LookUpBinding(reQuantity, CacheContext.YesNoCache(), "display", "value");
            UIUtils.LookUpBinding(reFZHS, CacheContext.YesNoCache(), "display", "value");
            UIUtils.LookUpBinding(reRate, CacheContext.GetCache("TRATE"), "FNAME", "SID");
        }

        void InitializeKindFilter()
        {
            var item = new DevExpress.XtraBars.BarSubItem(barManager1, "类别筛选");  // UIUtils.CreateBarItem<DevExpress.XtraBars.BarSubItem>(barManager1, bar2, "类别筛选", 4);

            foreach (var sub in CacheContext.GetCache("accSystem").AsEnumerable())
            {
                //var sItem = UIUtils.CreateBarItem<DevExpress.XtraBars.BarSubItem>(barManager1, bar2, sub["caption"].ToString(), 0, sItem_ItemClick);
                var sItem = new DevExpress.XtraBars.BarButtonItem(barManager1, sub["caption"].ToString()) { Tag = string.Format("FTYPE='{0}'", sub["key"]) };
                sItem.ItemClick += sItem_ItemClick;
                item.AddItem(sItem);
            }

            var sAll = new DevExpress.XtraBars.BarButtonItem(barManager1, "全部") { Tag = string.Empty };
            sAll.ItemClick += sItem_ItemClick;
            item.AddItem(sAll);
            bar2.LinksPersistInfo.Add(new DevExpress.XtraBars.LinkPersistInfo(item));
        }

        public override void InitializeViewUI()
        {

        }

        void sItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            var data = ViewModel["viewData"] as DataTable;
            data.DefaultView.RowFilter = e.Item.Tag.ToString();
        }

        protected override void FindProcess(string value)
        {
            var d = ViewModel["viewData"] as DataTable;
            var filter = d.Select(string.Format("FCODE LIKE '%{0}%' OR FNAME LIKE '%{0}%'", value));

            treeList1.DataSource = (filter.Length == 0) ? null : filter.CopyToDataTable();

            treeList1.Update();
            treeList1.ExpandAll();
        }

        protected override void NewProcess()
        {
            //一级科目
            if (treeList1.FocusedNode == null || treeList1.FocusedNode.ParentNode == null)
            {
                var data = treeList1.GetDataRecordByNode(treeList1.FocusedNode) as DataRowView;
                var code = CacheContext.GetCache("TACCOUNT").Compute("MAX(FCODE)"
                    , string.Format("FPARENT='{0}'", data["SID"]));
                var row = data.Row.Table.NewRow();
                row.ItemArray = data.Row.ItemArray;
                row["FCODE"] = (Agile.Engine.Utils.StringUtils.IsEmpty(code))
                    ? string.Format("{0}01", data["FCODE"]) : (Convert.ToInt32(code) + 1).ToString();
                row["FNAME"] = string.Empty;

                UIManager.ShowEdit<AccountEditForm>("AccountEditViewProvider"
                    , Agile.Engine.View.ViewState.AddNew
                    , Agile.Engine.Utils.DataUtils.ToEditModel("viewData", row));
            }
            ///点击的下级科目
            else if (treeList1.FocusedNode.ParentNode != null)
            {

                var data = treeList1.GetDataRecordByNode(treeList1.FocusedNode.ParentNode) as DataRowView;
                var code = CacheContext.GetCache("TACCOUNT").Compute("MAX(FCODE)"
                    , string.Format("FPARENT='{0}'", data["SID"]));
                var row = data.Row.Table.NewRow();
                row.ItemArray = data.Row.ItemArray;
                row["FCODE"] = (Convert.ToInt32(code) + 1).ToString();
                row["FNAME"] = string.Empty;

                UIManager.ShowEdit<AccountEditForm>("AccountEditViewProvider"
                    , Agile.Engine.View.ViewState.AddNew
                    , Agile.Engine.Utils.DataUtils.ToEditModel("viewData", row));

            }
            

            CacheContext.RefreshCache(ViewProvider.DataTableName);
            RefreshProcess();

        }

        protected override void EditProcess()
        {
            if (treeList1.FocusedNode == null)
                return;
            var data = treeList1.GetDataRecordByNode(treeList1.FocusedNode) as DataRowView;
            UIManager.ShowEdit<AccountEditForm>("AccountEditViewProvider"
                , Agile.Engine.View.ViewState.Modify
                , Agile.Engine.Utils.DataUtils.ToEditModel("viewData", data.Row));
            CacheContext.RefreshCache(ViewProvider.DataTableName);
            RefreshProcess();
        }

        protected override void DelProcess()
        {
            if (treeList1.FocusedNode == null)
                return;

            var data = treeList1.GetDataRecordByNode(treeList1.FocusedNode) as DataRowView;
            var d = ViewModel["viewData"] as DataTable;
            var children = d.Select(string.Format("FPARENT='{0}'", data["SID"]));

            //bugfix by yekai@不允许删除非子级科目
            if (children.Length > 0)
            {
                Message = "非子级科目不能删除。";
                return;
            }

            //bugfix by yekai@不允许删除固定科目
            if (data["FFIXEDACCOUNT"].Equals("1"))
            {
                Message = "固定模板科目不能删除。";
                return;
            }

            if (DialogResult.Yes == DevExpress.XtraEditors.XtraMessageBox.Show("确定要删除吗？", "提示", MessageBoxButtons.YesNo))
            {
                ViewModel["SID"] = data["SID"];
                ViewProvider.ExecuteUpdate(ViewModel);
                CacheContext.RefreshCache(ViewProvider.DataTableName);
                RefreshProcess();
            }
        }

        protected override void ExportProcess(string file)
        {
            var option = new DevExpress.XtraPrinting.XlsExportOptions();
            option.SheetName = Text;

            var source = treeList1.DataSource;
            treeList1.DataSource = null;
            treeList1.ParentFieldName = string.Empty;
            treeList1.DataSource = source;
            treeList1.ExportToXls(file, option);

            treeList1.DataSource = null;
            treeList1.ParentFieldName = "FPARENT";
            treeList1.DataSource = source;
            treeList1.ExpandAll();

        }

        public override string FromXls(string path)
        {
            var error = string.Empty;
            var data = DataTransUtils.ReadSheet(path, Text, ref error);

            //读取出错
            if (data == null)
            {
                return "Excel格式错误或者Excel中的Sheet名称不正确。";
            }

            ///实体数据
            DataTable source = (ViewModel["viewData"] as DataTable);
            DataTable schema = source.Copy();
            schema.Clear();

            #region 读取导入信息

            foreach (DataRow row in data.AsEnumerable())
            {
                //新行
                var newRow = schema.NewRow();

                var code = Agile.Engine.Utils.StringUtils.IsEmpty(row["科目编码"]) ? string.Empty : row["科目编码"].ToString();
                var name = Agile.Engine.Utils.StringUtils.IsEmpty(row["科目名称"]) ? string.Empty : row["科目名称"].ToString();
                var type = Agile.Engine.Utils.StringUtils.IsEmpty(row["科目类别"]) ? string.Empty : row["科目类别"].ToString();
                var jd = Agile.Engine.Utils.StringUtils.IsEmpty(row["余额方向"]) ? string.Empty : row["余额方向"].ToString();

                //代码或名称为空不处理
                if (string.IsNullOrEmpty(code) || string.IsNullOrEmpty(name))
                {
                    continue;
                }

                //类别为空
                if (string.IsNullOrEmpty(type))
                {
                    return string.Format("导入失败，原因：科目编码[{0}]科目名称[{1}]的科目类别为空", code, name);
                }

                //余额方向为空
                if (string.IsNullOrEmpty(jd))
                {
                    return string.Format("导入失败，原因：科目编码[{0}]科目名称[{1}]的余额方向为空", code, name);
                }

                //代码是固定会计科目不处理
                var cache = CacheContext.GetCache("TACCOUNT");
                var query = cache.Select(string.Format("FCODE='{0}'", code));
                if (query.Length > 0)
                {
                    if (query[0]["FFIXEDACCOUNT"].Equals("1"))
                        continue;
                }
                //代码不能重复
                var exits = schema.Select(string.Format("FCODE='{0}'", code));
                if (exits.Length > 0)
                {
                    return string.Format("导入失败，原因：科目编码[{0}]科目名称[{1}]重复定义", code, name);
                }
                //类别转换
                var types = CacheContext.GetCache("accSystem");// "caption", "key"
                var typeRow = types.Select(string.Format("caption='{0}'", type));
                if (typeRow.Length == 0)
                {
                    return string.Format("导入失败，原因：科目编码[{0}]科目名称[{1}]定义的科目类别[{2}]不存在", code, name, type);
                }
                //方向转换
                var jds = CacheContext.DebitCreditCache();//, "display", "value"
                var jdsRow = jds.Select(string.Format("display='{0}'", jd));
                if (jdsRow.Length == 0)
                {
                    return string.Format("导入失败，原因：科目编码[{0}]科目名称[{1}]定义的借贷方向[{2}]不存在", code, name, jd);
                }

                //赋值
                newRow["FCODE"] = code;
                newRow["FNAME"] = name;
                newRow["FTYPE"] = typeRow[0]["key"];
                newRow["FJD"] = jdsRow[0]["value"];
                newRow["FDETAILNAME"] = string.Format("{0}-{1}", code, name);
                newRow["FBZ"] = "defaultCurrencyRate";
                newRow["FWBHS"] = "0";
                newRow["FQUANTITY"] = "0";
                newRow["FISFZHS"] = "0";
                newRow["FFIXEDACCOUNT"] = "0";
                newRow["SID"] = "IMPORT_" + code;
                schema.Rows.Add(newRow);
            }

            #endregion
            #region 科目有效性验证
            var level = Fis.Win.Utils.AppSession.Book["FACCSTRUCT"].ToString();
            var l = level.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var d in schema.AsEnumerable())
            {
                var code = d["FCODE"].ToString();
                var len = 0;
                var parent = string.Empty;
                for (var i = 0; i < l.Length; i++)
                {
                    len += int.Parse(l[i]);
                    if (len > code.Length)
                    {
                        return string.Format("导入失败，原因：科目编码[{0}]结构错误，请参照{0}", code, level);
                    }
                    var c = code.Substring(0, len);

                    //一级科目
                    if (code.Length == len)
                    {
                        break;
                    }

                    if (i != l.Length - 1)
                    {
                        //缓存中取上级科目
                        var acc = Fis.Win.Utils.CacheContext.GetCache("TACCOUNT").Select(string.Format("FCODE='{0}'", c));
                        if (acc.Length == 0)
                        {
                            acc = schema.Select(string.Format("FCODE='{0}'", c));
                        }
                        if (acc.Length > 0)
                        {
                            d["FPARENT"] = acc[0]["SID"].ToString();
                        }
                        else
                        {
                            return string.Format("导入失败，原因：科目编码[{0}]上级科目不存在", code);
                        }
                    }
                    else
                    {
                        return string.Format("导入失败，原因：科目编码[{0}]结构错误，请参照{0}", code, level);
                    }
                }
            }
            #endregion

            if (schema.Rows.Count == 0)
            {
                return string.Format("导入失败，原因：没有有效的数据可以导入。\r\n 1,系统固定科目不会被导入 \r\n 2,科目代码或科目名称为空不会被导入");

            }
            ViewModel["viewData"] = schema;
            treeList1.Nodes.Clear();
            treeList1.DataSource = schema;
            treeList1.ExpandAll();
            return string.Empty;
        }


    }
}
